from django.db.models import Q
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from erp_system.tasks import create_menus_permissions
from erp_system.models import Menu, PermissionsModel
from erp_system.serializers.menus_serializer import MenuSerializer


class MenuViewSet(ModelViewSet):
    """
    create:
    功能菜单--新增

    功能菜单新增, status: 201(成功), return: 新增功能菜单信息

    destroy:
    功能菜单--删除

    功能菜单删除, status: 204(成功), return: None

    update:
    功能菜单--修改,全局修改

    功能菜单修改, status: 200(成功), return: 修改后的功能菜单信息

    partial_update:
    功能菜单--局部修改

    功能菜单批修改 status: 200(成功), return: 修改后的功能菜单信息

    list:
    功能菜单--获取列表

    功能菜单列表信息, status: 200(成功), return: 功能菜单信息列表

    retrieve:
    查询某一个功能菜单

    查询指定ID的功能菜单, status: 200(成功), return: 用户功能菜单

    find_parent:
    查询所有的顶级功能菜单， 不需要传参。

    get_menus_by_permission:
    查询当前登录的用户，所有的，拥有GET权限的菜单列表，而且这些菜单列表必须是树形结构

    返回树形菜单列表, status: 200(成功)
    """
    serializer_class = MenuSerializer
    queryset = Menu.objects.all()
    # 必须是登录成功之后才能访问所有功能菜单的接口
    # permission_classes = [IsAuthenticated]

    @action(methods=['get'], detail=False)
    def find_parent(self, request, *args, **kwargs):
        lst = self.get_queryset().filter(parent__isnull=True)
        ser = self.get_serializer(instance=lst, many=True)
        return Response(ser.data)

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        menu = serializer.save()
        # 发布异步的任务
        if menu and menu.id:
            create_menus_permissions.delay(menu.id)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    @action(methods=['get'], detail=False)
    def get_menus_by_permission(self, request, *args, **kwargs):
        # 得到当前登录用户
        user = request.user
        # 查询该用户所拥有的权限ID列表
        permission_id = user.roles.values_list('permissions', flat=True).distinct()
        # 过滤那些GET的，或者是顶级菜单权限
        menu_ids = PermissionsModel.objects.filter(Q(method='GET') | Q(is_menu=True)).filter(id__in=permission_id)\
            .values_list('menu', flat=True)

        # 根据menu_id得到菜单接口对象
        menu_list = Menu.objects.filter(id__in=menu_ids, delete_flag=0).all()

        serializer = MenuSerializer(instance=menu_list, many=True)
        # 定义 Element
        tree_dict = {}  # 代表一个父菜单
        tree_data = []
        try:
            for item in serializer.data:
                tree_dict[item['id']] = item
            for i in tree_dict:
                if tree_dict[i]['parent']:
                    pid = tree_dict[i]['parent']
                    parent = tree_dict[pid]
                    parent.setdefault('children', []).append(tree_dict[i])
                else:
                    tree_data.append(tree_dict[i])
            results = tree_data
        except KeyError:
            results = serializer.data
        return Response(results)
